var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var fs = require('fs');
const os = require('os');
const iconv = require('iconv-lite'); // 引入 iconv-lite

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const multer = require('multer');
const { exec } = require('child_process');

var app = express();

// 配置 multer 的存储方式
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0'); // 补零，例如 03
    const uploadPath = path.join('uploads', `${year}${month}`);

    // 如果目录不存在，则创建
    if (!fs.existsSync(uploadPath)) {
      fs.mkdirSync(uploadPath, { recursive: true });
    }
    cb(null, uploadPath);
  },
  filename: function (req, file, cb) {
    // 使用 iconv-lite 将文件名从原始编码（如 GBK）转换为 UTF-8
    const originalName = file.originalname;
    const decodedName = iconv.decode(Buffer.from(originalName, 'binary'), 'utf-8'); // 转换为 UTF-8
    cb(null, decodedName); // 使用转换后的文件名
  }
});

const upload = multer({ storage: storage });

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// 全局变量来跟踪是否有命令正在执行
let isCommandRunning = false;

app.post('/upload', upload.single('file'), (req, res) => {
  try {
    const filePath = req.file.path; // 文件保存路径
    const originalName = req.file.originalname; // 文件原始名称
    const fileSize = req.file.size; // 文件大小

    console.log(`文件保存路径: ${filePath}`); // 输出文件保存路径

    // 自动拼接完整的 APK 文件路径
    const fullApkFilePath = path.join(__dirname, filePath);

    // 检查并移除旧的签名文件
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0'); // 补零，例如 03
    const uploadPath = path.join('uploads', `${year}${month}`);
    const signedFilePath = path.join(uploadPath, originalName.replace('.apk', '_signed.apk'));

    if (fs.existsSync(signedFilePath)) {
      fs.unlinkSync(signedFilePath); // 移除旧的签名文件
      console.log(`已移除旧的签名文件: ${signedFilePath}`);
    }

    console.log('fullApkFilePath:', fullApkFilePath);

    // 执行签名命令
    if (isCommandRunning) {
      console.log('命令正在执行中，请稍后再试。');
      return res.json({ code: 400, msg: '命令正在执行中，请稍后再试。' });
    }

    isCommandRunning = true; // 设置命令正在执行的标志

    if (os.platform() === 'win32') {
      // 使用 spawn 代替 exec
      const spawn = require('child_process').spawn;
      const javaProcess = spawn('java', [
        '-jar', 
        'C:\\autosign\\autoSign-2.0.jar', 
        '-configFilePath', 
        'C:\\autosign\\signConfig.json', 
        '-toolsPath', 
        'C:\\autosign\\toolsPathConfig.json', 
        '-apkFilePath', 
        fullApkFilePath
      ], { 
        cwd: 'C:\\autosign',
        windowsHide: true,
        stdio: 'pipe'
      });

      javaProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
      });

      javaProcess.stderr.on('data', (data) => {
        console.error(`stderr: ${data}`);
      });

      javaProcess.on('error', (error) => {
        console.error('Java 进程启动失败:', error);
        isCommandRunning = false;
        return res.json({ code: 500, msg: 'Java 进程启动失败，请检查 Java 安装和环境变量设置' });
      });

      javaProcess.on('close', (code) => {
        isCommandRunning = false; // 重置命令执行标志
        console.log(`子进程退出，退出码 ${code}`);
        if (code === 0) {
          return res.json({ code: 200, msg: '签名过程成功' });
        } else {
          console.error(`签名过程失败，退出码 ${code}`);
          return res.json({ code: 500, msg: `签名过程失败，退出码 ${code}` });
        }
      });

      // 启动Java进程后，直接返回，等待close事件处理响应
      return;

    } else {
      // 处理其他平台的命令
      let cmdCommand;
      if (os.platform() === 'darwin') {
        cmdCommand = `osascript -e 'tell application "Terminal" to do script "cd /autosign && java -jar autoSign-2.0.jar -configFilePath /autosign/signConfig.json -toolsPath /autosign/toolsPathConfig.json -apkFilePath ${fullApkFilePath} && sleep 3"'`;
      } else {
        cmdCommand = `gnome-terminal -- bash -c 'cd /autosign && java -jar autoSign-2.0.jar -configFilePath /autosign/signConfig.json -toolsPath /autosign/toolsPathConfig.json -apkFilePath ${fullApkFilePath}; sleep 3; exec bash'`;
      }

      exec(cmdCommand, (error, stdout, stderr) => {
        isCommandRunning = false;
        if (error) {
          console.error(`exec error: ${error}`);
          return res.json({ code: 500, msg: '执行命令失败' }); // 返回错误响应
        }
        console.log(`stdout: ${stdout}`);
        console.error(`stderr: ${stderr}`);
        return res.json({ code: 200, msg: '文件上传成功' }); // 在这里发送成功响应
      });
    }
  } catch (err) {
    console.error('上传处理失败:', err);
    isCommandRunning = false;
    return res.json({ code: 500, msg: '上传处理失败' });
  }
});

// 下载签名文件接口
app.get('/download-signed-apk', (req, res) => {
  const fileName = req.query.fileName; // 从查询参数获取文件名
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0'); // 补零，例如 03
  const uploadPath = path.join('uploads', `${year}${month}`);
  
  const filePath = path.resolve(__dirname, uploadPath, fileName); // 拼接完整的文件路径
  console.log('filePath', filePath, fileName);

  // 检查文件是否存在
  if (!fs.existsSync(filePath)) {
    return res.json({ code: 404, msg: '未找到签名文件' }); // 返回 404 错误
  }

  // 获取局域网 IP 地址
  const networkInterfaces = os.networkInterfaces();
  let localIP = '';
  for (const interfaceName in networkInterfaces) {
    for (const net of networkInterfaces[interfaceName]) {
      if (net.family === 'IPv4' && !net.internal) {
        localIP = net.address; // 获取第一个非内部的 IPv4 地址
        break;
      }
    }
    if (localIP) break; // 找到后退出循环
  }

  // 使用局域网 IP 地址生成下载链接
  const downloadUrl = `http://${localIP}:3000/download-signed-apk?fileName=${encodeURIComponent(fileName)}`;
  
  // 使用 res.download 进行文件下载
  res.download(filePath, fileName, (err) => {
    if (err) {
      // 处理下载错误
      if (err.code === 'ECONNABORTED') {
        console.warn('下载请求被中止:', err);
        return; // 不再发送响应
      }
      console.error('下载文件失败:', err);
      // 处理其他错误
      return res.json({ code: 500, msg: '下载文件失败' });
    }
  });
});

// 是否签名接口
app.get('/check-signed-file', (req, res) => {
  let fileName = req.query.fileName; // 从查询参数获取当前上传的文件名
  console.log('Received fileName:', fileName);

  if (!fileName) {
    return res.json({ code: 400, msg: '缺少文件名参数' }); // 如果没有文件名参数，返回 400 错误
  }

  // 检查文件名是否符合预期格式
  if (!fileName.endsWith('.apk')) {
    return res.json({ code: 400, msg: '文件名格式不正确，必须以 .apk 结尾' }); // 返回 400 错误
  }
  const signedFileName = fileName.replace('.apk', '_signed.apk'); // 生成签名文件名
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0'); // 补零，例如 03
  const uploadPath = path.join('uploads', `${year}${month}`);

  // 检查上传路径是否存在
  if (!fs.existsSync(uploadPath)) {
    return res.json({ code: 500, msg: `上传路径不存在: ${uploadPath}` }); // 返回 500 错误
  }

  fs.readdir(uploadPath, (err, files) => {
    if (err) {
      console.error('读取目录失败:', err);
      return res.json({ code: 500, msg: '读取目录失败' });
    }

    const signedFile = files.find(file => file === signedFileName); // 检查是否存在对应的签名文件
    if (signedFile) {
      const downloadUrl = `http://localhost:3000/download-signed-apk?fileName=${encodeURIComponent(signedFile)}`; // 生成下载链接
      return res.json({ code: 200, msg: '签名文件存在', downloadUrl, fileName: signedFile });
    }
    return res.json({ code: 404, msg: '签名文件不存在' });
  });
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.json({ code: err.status || 500, msg: '服务器错误' });
});

module.exports = app;
const port = process.env.PORT || 8888; // 使用环境变量 PORT 或默认端口 3000
app.listen(port, () => {
  console.log(`服务器正在运行，访问地址：http://localhost:${port}`);
});